package com.wifi.utils;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.location.LocationManager;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;

import com.wifi.BaseApplication;
import com.wifi.eshipewifi.SocThread;
import com.wifi.imp.MessageSend;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

public class WifiUtils {
	private WifiManager localWifiManager;//提供Wifi管理的各种主要API，主要包含wifi的扫描、建立连接、配置信息等
	private LocationManager locManager ;//gps
	//private List<ScanResult> wifiScanList;//ScanResult用来描述已经检测出的接入点，包括接入的地址、名称、身份认证、频率、信号强度等
	private List<WifiConfiguration> wifiConfigList;//WIFIConfiguration描述WIFI的链接信息，包括SSID、SSID隐藏、password等的设置
	private WifiInfo wifiConnectedInfo;//已经建立好网络链接的信息
	private WifiLock wifiLock;//手机锁屏后，阻止WIFI也进入睡眠状态及WIFI的关闭
	BaseApplication application;
	Context mContext;
	public WifiUtils(Context context){
		this.mContext=context;
		localWifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
		locManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);

		application=new BaseApplication();
	}
	public WifiUtils(WifiManager localWifiManager){
		this.localWifiManager=localWifiManager;
	}

	public String getConnectWifiSsid(){//获取当前所连接的wifi ssid
//		WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
		WifiInfo wifiInfo = localWifiManager.getConnectionInfo();
		Log.d("wifiInfo", wifiInfo.toString());
		Log.d("SSID",wifiInfo.getSSID());
		return wifiInfo.getSSID();
	}

	public String getMacAddress() {
		String result = "";
		String Mac = "";
		result = callCmd("busybox ifconfig", "HWaddr");

		if (result == null) {
			return "网络出错，请检查网络";
		}
		if (result.length() > 0 && result.contains("HWaddr")) {
			Mac = result.substring(result.indexOf("HWaddr") + 6, result.length() - 1);
			if (Mac.length() > 1) {
				result = Mac.toLowerCase();
			}
		}
		return result.trim();
	}


	public String callCmd(String cmd,String filter) {
		String result = "";
		String line = "";
		try {
			Process proc = Runtime.getRuntime().exec(cmd);
			InputStreamReader is = new InputStreamReader(proc.getInputStream());
			BufferedReader br = new BufferedReader(is);

			//执行命令cmd，只取结果中含有filter的这一行
			while ((line = br.readLine ()) != null && line.contains(filter)== false) {
				//result += line;
				Log.i("test","line: "+line);
			}

			result = line;
			Log.i("test","result: "+result);
		}
		catch(Exception e) {
			e.printStackTrace();
		}
		return result;
	}



	//循环搜索wifi并连接,把thread保存到application ---不更改wifi name
	public void WifiReboot(Handler mhandler, Handler mhandlerSend, Context context, BaseApplication application){
		List<String> wifiListString = new ArrayList<String>();
		SharedPreferences sp= context.getSharedPreferences("wifiSetting", Activity.MODE_PRIVATE);
		String ssid = sp.getString("ssid", "sn1111111");//todo 以后要改,默认账号 sn1111111要改
		String password = sp.getString("password", "czd5d323");
		getConfiguration();
		//循环搜索wifi
//		List<ScanResult> wifiResultList = this.getScanResults();
		if(wifiListString != null){
			try {
				Thread.sleep(10000);
				scanResultToString( wifiListString,ssid);//循环搜索指定wifi
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		int wifiItemId = this.IsConfiguration(ssid);//todo 判断是否为配置过的wifi，日后逻辑会出错
		Log.i("ListOnItemClickListener",String.valueOf(wifiItemId));
		if(wifiItemId != -1){
			if(this.ConnectWifi(wifiItemId)){//连接指定WIFI
				//重新new 一个SocThread
				try {
					Thread.sleep(2000);//1秒延时
					SocThread thread = new SocThread(mhandler, mhandlerSend, context,"192.168.8.1");
					thread.start();
					((MessageSend)context).GetNewThread(thread);
					application.setThread(thread);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
//                                    thread.Send("$first_connet;");
				Toast.makeText(context,"重新连接wifi成功,$first_connet",Toast.LENGTH_SHORT).show();
			}
		}
	}

	Context contextReboot;
	BaseApplication applicationReboot;
	String SSidnameReboot;
	String passwordReboot;
	public void WifiRebootForSetName(final Context context, final BaseApplication application, final String SSidname, final String password){
		this.contextReboot=context;
		this.applicationReboot=application;
		this.SSidnameReboot=SSidname;
		this.passwordReboot=password;
		Observable.create(new Observable.OnSubscribe<String>() {
			@Override
			public void call(Subscriber<? super String> subscriber) {
				//断线重连
				WifiRebootForSetNameRxjava(context,application,SSidname,password);
				subscriber.onNext("");
				subscriber.onCompleted();
			}
		}).subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
				.observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
				.subscribe(new Action1<String>() {
					@Override
					public void call(String s) {
						if(s!=null){
							Log.d("rx","------正在后台扫描WIFI并重新连接："+s);
						}
					}
				});

	}


	//循环搜索wifi并连接,把thread保存到application  ----更改 wifi name
	public void WifiRebootForSetNameRxjava( Context context, BaseApplication application,String SSidname,String password){
		List<String> wifiListString = new ArrayList<String>();
		getConfiguration();
		//循环搜索wifi
		if(wifiListString != null){
			try {
//todo				Thread.sleep(8000);
				scanResultToString( wifiListString,SSidname);//循环搜索指定wifi
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		int wifiItemId = this.IsConfiguration(SSidname);//todo 判断是否为配置过的wifi，日后逻辑会出错
		if(wifiItemId != -1){
			if(this.ConnectWifi(wifiItemId)){//连接指定WIFI
//				Toast.makeText(context,"连接成功",Toast.LENGTH_SHORT).show();
			}else{
//				Toast.makeText(context, "网络连接错误", Toast.LENGTH_SHORT).show();
			}
		}else{//没有配置好信息，后台配置
			if(password != null && SSidname!=null){
				List<ScanResult> wifiResultList = this.getScanResults();
				int netId = this.AddWifiConfig(wifiResultList,SSidname, password);
				Log.i("WifiPswDialog",String.valueOf(netId));
				if(netId != -1){
					this.getConfiguration();//添加了配置信息，要重新得到配置信息
					Toast.makeText(context,"连接成功",Toast.LENGTH_SHORT).show();
//					if(this.ConnectWifi(netId)){
//						//连接成功
//						//重新new 一个SocThread
//						try {
//							Thread.sleep(18000);//12秒延时
//							String ip = application.getIp();
//							//新建socket
//							SocThread thread = new SocThread(mhandler, mhandlerSend, context,ip);
//							thread.start();
//							((MessageSend)context).GetNewThread(thread);
//							application.setThread(thread);
//						} catch (InterruptedException e) {
//							e.printStackTrace();
//						}
//					}
				}
				else{
					Toast.makeText(context, "网络连接错误", Toast.LENGTH_SHORT).show();
				}
			}
		}
	}

	//循环搜索wifi并连接,把thread保存到application  ----更改 wifi name
	public void WifiRebootForSetName(String SSidname,String password){
		List<String> wifiListString = new ArrayList<String>();
		getConfiguration();
		//循环搜索wifi
		if(wifiListString != null){
			try {
//todo				Thread.sleep(8000);
				scanResultToString( wifiListString,SSidname);//循环搜索指定wifi
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		int wifiItemId = this.IsConfiguration(SSidname);//todo 判断是否为配置过的wifi，日后逻辑会出错
		if(wifiItemId != -1){
			if(this.ConnectWifi(wifiItemId)){//连接指定WIFI
//				Toast.makeText(context,"连接成功",Toast.LENGTH_SHORT).show();
			}else{
//				Toast.makeText(context, "网络连接错误", Toast.LENGTH_SHORT).show();
			}
		}else{//没有配置好信息，后台配置
			if(password != null && SSidname!=null){
				List<ScanResult> wifiResultList = this.getScanResults();
				int netId = this.AddWifiConfig(wifiResultList,SSidname, password);
				Log.i("WifiPswDialog",String.valueOf(netId));
				if(netId != -1){
					this.getConfiguration();//添加了配置信息，要重新得到配置信息
//					Toast.makeText(context,"连接成功",Toast.LENGTH_SHORT).show();
				}
				else{
//					Toast.makeText(context, "网络连接错误", Toast.LENGTH_SHORT).show();
				}
			}
		}
	}



	/**
	 * if (intf.getName().toLowerCase().equals("eth0") || intf.getName().toLowerCase().equals("wlan0"))
	 * 表示:仅过滤无线和有线的ip. networkInterface是有很多的名称的
	 * 比如sim0,remt1.....等等.我不需要用到就直接过滤了
	 *
	 * if (!ipaddress.contains("::"))
	 * 表示: 过滤掉ipv6的地址.不管无线还是有线 都有这个地址,
	 * 我这边显示地址大体是:fe80::288:88ff:fe00:1%eth0 fe80::ee17:2fff:fece:c0b4%wlan0
	 * 一般都是出现在第一次循环.第二次循环就是真正的ipv4的地址.
	 *
	 * @return
	 * @throws SocketException
	 */
	public String GetIpAddress() throws SocketException {
		String ipaddress = "";
		Enumeration<NetworkInterface> netInterfaces = null;
		try {
			netInterfaces = NetworkInterface.getNetworkInterfaces();
			while (netInterfaces.hasMoreElements()) {
				NetworkInterface intf = netInterfaces.nextElement();
				if (intf.getName().toLowerCase().equals("eth0") || intf.getName().toLowerCase().equals("wlan0")) {
					for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
						InetAddress inetAddress = enumIpAddr.nextElement();
						if (!inetAddress.isLoopbackAddress()) {
							ipaddress = inetAddress.getHostAddress().toString();
							if (!ipaddress.contains("::")) {// ipV6的地址
								ipaddress = ipaddress;
							}
						}
					}
				} else {
					continue;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
// final ContentResolver mContentResolver = getContentResolver();
// Settings.System.putInt( mContentResolver,
// Settings.System.WIFI_USE_STATIC_IP, 1);
// Settings.System.putString( mContentResolver,
// Settings.System.WIFI_STATIC_IP, "你的ip地址");

		return ipaddress;
	}




	//ScanResult类型转为String
	public void scanResultToString(List<String> listStr,String ssid){
			boolean flag=false;
			while (!flag){
				List<ScanResult> wifiResultList = this.getScanResults();
				for(int i = 0; i <wifiResultList.size(); i++){
					ScanResult strScan = wifiResultList.get(i);
					String str = strScan.SSID;
					if(str.indexOf(ssid)!=-1){//todo 以后逻辑要改
						flag=true;
						return;
					}
				}
		}
	}


	//检查WIFI状态
	public int WifiCheckState(){
		return localWifiManager.getWifiState();
	}

	//开启WIFI
	public void WifiOpen(){
		if(!localWifiManager.isWifiEnabled()){
			localWifiManager.setWifiEnabled(true);
		}
	}

	//关闭WIFI
	public void WifiClose(){
		if(!localWifiManager.isWifiEnabled()){
			localWifiManager.setWifiEnabled(false);
		}
	}

	//扫描wifi
	public void WifiStartScan(){
		localWifiManager.startScan();
	}

	//得到Scan结果
	public List<ScanResult> getScanResults(){
//		Log.i("wifi列表", String.valueOf(localWifiManager.getScanResults()));
		if (Build.VERSION.SDK_INT >= 23 ) {

			if(!locManager.isProviderEnabled(LocationManager.GPS_PROVIDER))
			{
				// 未打开位置开关，可能导致定位失败或定位不准，提示用户或做相应处理
				Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.LOCATION_MODE, 1);
			}

		}
		return localWifiManager.getScanResults();//得到扫描结果
	}

	//Scan结果转为Sting
	public List<String> scanResultToString(List<ScanResult> list){
		List<String> strReturnList = new ArrayList<String>();
		for(int i = 0; i < list.size(); i++){
			ScanResult strScan = list.get(i);
			String str = strScan.toString();
			boolean bool = strReturnList.add(str);
			if(!bool){
				Log.i("scanResultToSting","Addfail");
			}
		}
		return strReturnList;
	}

	//得到Wifi配置好的信息
	public void getConfiguration(){
		wifiConfigList = localWifiManager.getConfiguredNetworks();//得到配置好的网络信息
		for(int i =0;i<wifiConfigList.size();i++){
//			Log.i("getConfiguration",wifiConfigList.get(i).SSID);
//			Log.i("getConfiguration", String.valueOf(wifiConfigList.get(i).networkId));
		}
	}
	//判定指定WIFI是否已经配置好,依据WIFI的地址BSSID,返回NetId
	public int IsConfiguration(String SSID){
//		Log.i("IsConfiguration", String.valueOf(wifiConfigList.size()));
		for(int i = 0; i < wifiConfigList.size(); i++){
			Log.i(wifiConfigList.get(i).SSID, String.valueOf( wifiConfigList.get(i).networkId));
			if(wifiConfigList.get(i).SSID.lastIndexOf(SSID)!=-1){//地址相同
				return wifiConfigList.get(i).networkId;
			}
		}
		return -1;
	}

	//添加指定WIFI的配置信息,原列表不存在此SSID
	public int AddWifiConfig(List<ScanResult> wifiList, String ssid, String pwd){
		int wifiId = -1;
		for(int i = 0;i < wifiList.size(); i++){
			ScanResult wifi = wifiList.get(i);
			if(wifi.SSID.indexOf(ssid)!=-1){
				Log.i("AddWifiConfig","equals");
				WifiConfiguration wifiCong = new WifiConfiguration();
				wifiCong.SSID = "\""+wifi.SSID+"\"";//\"转义字符，代表"
				wifiCong.preSharedKey = "\""+pwd+"\"";//WPA-PSK密码
				wifiCong.hiddenSSID = false;
				wifiCong.status = WifiConfiguration.Status.ENABLED;
				wifiId = localWifiManager.addNetwork(wifiCong);//将配置好的特定WIFI密码信息添加,添加完成后默认是不激活状态，成功返回ID，否则为-1
				if(wifiId != -1){
					return wifiId;
				}
			}
		}
		return wifiId;
	}

	//连接指定Id的WIFI
	public boolean ConnectWifi(int wifiId){
		for(int i = 0; i < wifiConfigList.size(); i++){
			WifiConfiguration wifi = wifiConfigList.get(i);
			if(wifi.networkId == wifiId){
				while(!(localWifiManager.enableNetwork(wifiId, true))){//激活该Id，建立连接
					Log.d("ConnectWifi", String.valueOf(wifiConfigList.get(wifiId).status));//status:0--已经连接，1--不可连接，2--可以连接
				}
				return true;
			}
		}
		return false;
	}

	//创建一个WIFILock
	public void createWifiLock(String lockName){
		wifiLock = localWifiManager.createWifiLock(lockName);
	}

	//锁定wifilock
	public void acquireWifiLock(){
		wifiLock.acquire();
	}

	//解锁WIFI
	public void releaseWifiLock(){
		if(wifiLock.isHeld()){//判定是否锁定
			wifiLock.release();
		}
	}

	//得到建立连接的信息
	public void getConnectedInfo(){
		wifiConnectedInfo = localWifiManager.getConnectionInfo();
	}
	//得到连接的MAC地址
	public String getConnectedMacAddr(){
		return (wifiConnectedInfo == null)? "NULL":wifiConnectedInfo.getMacAddress();
	}

	//得到连接的名称SSID
	public String getConnectedSSID(){
		return (wifiConnectedInfo == null)? "NULL":wifiConnectedInfo.getSSID();
	}

	//得到连接的IP地址
	public int getConnectedIPAddr(){
		return (wifiConnectedInfo == null)? 0:wifiConnectedInfo.getIpAddress();
	}

	//得到连接的ID
	public int getConnectedID(){
		return (wifiConnectedInfo == null)? 0:wifiConnectedInfo.getNetworkId();
	}
}
